 /*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * Project  : kindlepush
 * Package  : net.solosky.kindlepush.book
 * File     : PdfBookBuilder.java
 * Author   : solosky < solosky772@qq.com >
 * Created  : 2012-4-19
 * License  : Apache License 2.0 
 */
package net.solosky.kindlepush.forum.book;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.solosky.kindlepush.forum.bean.Post;
import net.solosky.kindlepush.forum.bean.Topic;

import org.jsoup.Jsoup;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Chapter;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Section;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;

/**
 *
 * 生成PDF的电子书实现，对Kindle做了特别的优化
 *
 * @author solosky <solosky772@qq.com>
 *
 */
public class PdfBookBuilder implements BookBuilder{
	private static BaseFont SIMSUN_FONT;
	private static Font 	  TEXT_FONT;
	private List<Chapter> chapters;
	
	static{
		try {
			SIMSUN_FONT = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
			TEXT_FONT   = new Font(SIMSUN_FONT, 26);
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
	}
	
	public PdfBookBuilder() throws Exception{
		chapters = new ArrayList<Chapter>();
	}

	@Override
	public void writeTopic(String chapterName, Topic topic) throws Exception{
		Paragraph title = new Paragraph(chapterName, TEXT_FONT);
		Chapter chapter = new Chapter(title, 1);
		chapter.setNumberDepth(0);
		chapters.add(chapter);
		
		Paragraph topicName = new Paragraph(topic.getTitle(), new Font(SIMSUN_FONT, 28, Font.BOLD));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		chapter.add(new Paragraph("\n\n\n\n"));
		chapter.add(topicName);
		chapter.add(new Paragraph("\n\n\n\n\n\n"));
		chapter.add(new Paragraph("帖子作者: "+topic.getAuthor(), TEXT_FONT));
		chapter.add(new Paragraph("发表时间: "+sdf.format(topic.getPostDate()), TEXT_FONT));
		chapter.add(new Paragraph("帖子网址: "+topic.getMainUrl(), TEXT_FONT));
		chapter.add(new Paragraph("由 www.kindlepush.com 创建", TEXT_FONT));
	}

	@Override
	public void writePosts(String chapterName, String sectionName, List<Post> posts) throws Exception{
		Chapter curChapter = null;
		for(Chapter chapter: chapters){
			if(chapter.getTitle().getContent().equals(chapterName)){
				curChapter = chapter;
				break;
			}
		}
		
		if(curChapter==null){
			Paragraph title = new Paragraph(chapterName, TEXT_FONT);
			curChapter = new Chapter(title, 1);
			curChapter.setNumberDepth(0);
			chapters.add(curChapter);
		}
		
		Paragraph title = new Paragraph(sectionName, TEXT_FONT);
		Section section = curChapter.addSection(title);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for(Post post: posts){
			StringBuffer buffer = new StringBuffer();
			buffer.append("===========================================\n");
			buffer.append("# ");
			buffer.append(post.getFloor());
			buffer.append("楼   作者：");
			buffer.append(post.getAuthor());
			buffer.append("  发表时间：");
			buffer.append(sdf.format(post.getDate()==null ? new Date():post.getDate()));
			buffer.append("\n");
			buffer.append("===========================================\n");
			
			Font headFont = new Font(SIMSUN_FONT, 22, Font.NORMAL);
			Paragraph postHead = new Paragraph(buffer.toString(), headFont);
			postHead.setLeading((float) (headFont.getSize()*1.2));
			com.itextpdf.text.Element postBody = buildNode(Jsoup.parse(post.getText().replaceAll("[\\\r\\\n]", "")).body());
			Paragraph postEnd = new Paragraph("\n", headFont);
			section.add(postHead);
			section.add(postBody);
			section.add(postEnd);
		}
	}

	@Override
	public void saveBook(File file) throws Exception {
		Document document = new Document(new Rectangle(600, 800), 10, 10, 10, 10);
		PdfWriter.getInstance(document, new FileOutputStream(file));
		
		document.open();
		document.addAuthor("kindlepush.com");
		document.addCreator("kindlepush.com PdfBookBuilder");
		document.addCreationDate();
		for(Chapter chapter: chapters){
			document.add(chapter);
		}
		document.close();
	}
	
	private static com.itextpdf.text.Element buildNode(org.jsoup.nodes.Node node) throws BadElementException, MalformedURLException, IOException{
		if(node instanceof org.jsoup.nodes.TextNode){
			return new Chunk(((org.jsoup.nodes.TextNode) node).text(), TEXT_FONT);
		}else if(node instanceof org.jsoup.nodes.Element){
			org.jsoup.nodes.Element el = (org.jsoup.nodes.Element) node;
			String tagName = el.tagName().toLowerCase();
			if(tagName.equals("br")){
				return new Chunk("\n", TEXT_FONT);
			}else if(tagName.equals("img")){
				return new Chunk("[图片]", TEXT_FONT);
			}else if(tagName.equals("a")){
				com.itextpdf.text.Anchor anchor = new com.itextpdf.text.Anchor(el.text(), TEXT_FONT);
				 anchor.setName("LINK");
				 anchor.setReference(el.attr("href"));
				 return anchor;
			}else{
				Paragraph para = new Paragraph();
				para.setFont(TEXT_FONT);
				para.setLeading((float) (TEXT_FONT.getSize()*1.2));
				List<org.jsoup.nodes.Node> children = el.childNodes();
				for(org.jsoup.nodes.Node child: children){
					para.add(buildNode(child));
				}
				return para;
			}
		}else{
			throw new IllegalStateException("unexpected node type:"+node);
		}
	}

}
